package com.ohuang.test_compose.composeView

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput

/**
 * PageRoute功能相同
 * 但是PageSlice会保存之前的界面
 */
class PageSliceManager()  {
    private var pageSliceStack = java.util.ArrayList<PageSliceObj>()
    private var listState = java.util.ArrayList<MutableState<PageState>>() //控制索引位置的下一个page的状态
    private var rootState = mutableStateOf(PageState.None) //控制根page状态
    private var needFinish = false
    private var lazyCallBack: (() -> Unit)? = null
    private var finishCallBack: (() -> Unit)? = null
    private var animationEnable = true

    private fun getState(position: Int): MutableState<PageState> {
        val p = position - 1
        if (p < 0) {
            return rootState
        }

        return listState[p]
    }

    private fun getSlice(position: Int): PageSliceObj? {
        if (position >= pageSliceStack.size) {
            return null
        }
        return pageSliceStack[position]
    }

    private fun callLazy() {
        val callback = lazyCallBack
        lazyCallBack = null
        callback?.invoke()
    }

    private fun callFinish() {
        var callback = finishCallBack
        finishCallBack = null
        callback?.invoke()
    }

    fun animationEnable(boolean: Boolean) {
        animationEnable = boolean
    }

    /**
     * 立即结束当前compose  没有动画
     */
    fun finish(): Boolean {
        needFinish = false
        return if (pageSliceStack.isEmpty()) {
            false
        } else {
            var removeLast = pageSliceStack.removeLast()
            removeLast.removeCallBack.invoke()
            listState.removeLast()
            if (pageSliceStack.isEmpty()) {
                rootState.value = PageState.None
            } else {
                listState[listState.size - 1].value = PageState.None
            }
            true
        }
    }

    /**
     * 结束当前compose  带动画
     *
     */
    fun goBack(): Boolean {
        if (pageSliceStack.isEmpty()) {
            return false
        } else {
            getState(pageSliceStack.size - 1).value = PageState.Finish
            needFinish = true
            return true
        }
    }

    /**
     * 打开一个Composable
     */
    fun start(removeCallBack: () -> Unit = {}, content: (@Composable () -> Unit)) {
        if (needFinish) {
            return
        }
        pageSliceStack.add(PageSliceObj(content, removeCallBack))
        if (listState.isEmpty()) {
            listState.add(mutableStateOf(PageState.None))
            rootState.value = PageState.Start
        } else {
            val sate = listState[listState.size - 1]
            listState.add(mutableStateOf(PageState.None))
            sate.value = PageState.Start
        }
    }

    fun lazyStart(removeCallBack: () -> Unit = {}, content: (@Composable () -> Unit)) {
        lazyCallBack = { start(removeCallBack, content) }
    }

    /**
     * 替换
     */
    fun replace(removeCallBack: () -> Unit = {}, content: (@Composable () -> Unit)) {
        finish()
        lazyCallBack = { start(removeCallBack, content) }

    }

    fun finishToStart(removeCallBack: () -> Unit = {}, content: (@Composable () -> Unit)) {
        goBack()
        finishCallBack = {
            lazyStart(removeCallBack, content)
        }

    }


    /**
     * 判断是否还有page
     */
    fun isEmpty(): Boolean {
        return pageSliceStack.isEmpty()
    }

    @Composable
    private fun PageSliceImpl(pageSliceManager: PageSliceManager, position: Int = 0, color: Color) {

        val state = pageSliceManager.getState(position) //用于触发方法刷新
        val isShow = state.value
        var scale: Float = 0f
        scale = if (pageSliceManager.animationEnable) {
            val scale2: Float by animateFloatAsState(
                if (isShow == PageState.Start) 1f else 0f,
                animationSpec = spring(stiffness = 600f)
            )
            scale2
        } else {
            if (isShow == PageState.Start) 1f else 0f
        }
        //用于触发方法刷新
        if (isShow == PageState.Finish && scale <= 0f) {
            pageSliceManager.finish()
            pageSliceManager.callFinish()
        }
        val slice = pageSliceManager.getSlice(position)

        slice?.let {
            Box(modifier = Modifier
                .alpha(scale)
                .graphicsLayer(scaleX = scale, scaleY = scale)
                .background(color = color)
                .fillMaxHeight()
                .fillMaxWidth()
                .pointerInput(Unit) {  //防止点击穿透
                }
            ) {
                slice.content()
                PageSliceImpl(pageSliceManager = pageSliceManager, position = position + 1, color)
            }
        }
        pageSliceManager.callLazy()
    }

    @Composable
    fun CreatePageSlice(
        content: @Composable () -> Unit,
        pageSliceManager: PageSliceManager,
        color: Color
    ) {
        Box() {
            content()
            PageSliceImpl(pageSliceManager = pageSliceManager, position = 0, color = color)
        }
    }


}

enum class PageState {
    None, Start, Finish
}

internal class PageSliceObj(val content: (@Composable () -> Unit), var removeCallBack: () -> Unit) {
}



/**
 * content 不会被加入到PageSliceManager中
 */
@Composable
fun PageSlice(
    pageSliceManager: PageSliceManager,
    color: Color = Color.White,
    content: (@Composable() () -> Unit) = {}
) {
    pageSliceManager.CreatePageSlice(content, pageSliceManager, color)
}




